import React, { useCallback, useEffect, useMemo, useState } from "react";
import { BetaSchemaForm } from '@ant-design/pro-components';
import { useTimeout } from "ahooks";
import './index.less';
import classNames from "classnames";
import { Button, Space } from "antd";
import $ from 'jquery';

const useEventListener = <K extends keyof HTMLElementEventMap,>(eventName: K, target: HTMLElement | undefined, handler: (e: HTMLElementEventMap[K]) => void) => {
    useEffect(() => {
        target?.addEventListener(eventName, handler);
        return () => {
            target?.removeEventListener(eventName, handler);
        }
    }, [eventName, handler, target]);
}


function setTopAsync(_element: HTMLElement, top: number) {
    return new Promise<void>(() => {
        setTimeout(() => {
            _element.style.top = `${top + 30}px`;
            _element.setAttribute("data-top", `${top}`);
        }, 0);
    });
}


const useLongPress = () => {
    const [columns, setColumns] = useState([
        {
            name: "a",
            title: "1",
            dataIndex: "a",
            valueType: "text",
            formItemProps: {
                className: "abc",
            },
            fieldProps: {
                placeholder: "输入框"
            }
        },
        {
            name: "a",
            title: "2",
            dataIndex: "ab",
            valueType: "text",
            formItemProps: {
                className: "abc"
            },
            fieldProps: {
                placeholder: "输入框"
            }
        },
        {
            name: "a",
            title: "3",
            dataIndex: "ac",
            valueType: "text",
            formItemProps: {
                className: "abc"
            },
            fieldProps: {
                placeholder: "输入框"
            }
        }
    ])

    const [element, setElement] = useState<HTMLElement>();
    const [position, setPosition] = useState<{ x: number, y: number }>();
    const [change, setChange] = useState<{ from: number, to: number }>();

    const getSort = useCallback((element: HTMLElement) => {
        if (!element) {
            return 0;
        }
        let sort: number = 0;
        element.classList.forEach(p => {
            if (p.startsWith("abc-")) {
                sort = parseInt(p.split("-")[1]);
            }
        })
        return sort;
    }, [])

    const findParent = useCallback((element: HTMLElement, className: string): HTMLElement | undefined => {
        if (!element) {
            return undefined;
        }
        else if (element.classList.contains(className)) {
            return element;
        } else {
            return findParent(element.parentElement as HTMLElement, className);
        }
    }, [element])

    const clearTimer = useTimeout(() => {
        // 获取所有class 为abc的元素
        const elements = document.querySelectorAll(".abc") as NodeListOf<HTMLElement>;
        let wrap = document.querySelector(".form-wrap")! as HTMLElement;
        let submitWrap = document.querySelector(".form-container-submit") as HTMLElement;
        wrap.style.height = `${wrap.clientHeight}px`;
        submitWrap.style.position = "absolute";
        submitWrap.style.bottom = "0px";

        // wrap.style.paddingTop = `${wrap.clientHeight - submitWrap.clientHeight}px`;
        let _top = 0;
        let _allTop = 0;
        elements.forEach((_element) => {
            _element.style.position = "absolute";

            if (_element !== element) {
                _element.style.top = `${_allTop}px`;
                setTopAsync(_element, _top)
                _top += _element.clientHeight;
            }
            else {
                setTopAsync(_element, _allTop)
                _element.style.top = `${_allTop}px`;
            }
            _allTop += _element.clientHeight;
        })
        element?.classList.add("long");
    }, element && 10);

    const moveFunc = useCallback((e: MouseEvent) => {
        if (element && position) {
            let elementSort: number = 0;
            element.classList.forEach(p => {
                if (p.startsWith("abc-")) {
                    elementSort = parseInt(p.split("-")[1]);
                }
            })
            const { clientX, clientY } = e;
            const { x, y } = position;
            const moveX = clientX - x;
            const moveY = clientY - y;
            element.style.transform = `translate(${moveX}px, ${moveY - 5}px)`;
            // 判断是否移动到另外class为abc的边缘
            const _element = document.elementFromPoint(clientX, clientY);
            if (!_element) return;
            const dragElement = findParent(_element as HTMLElement, "abc");
            if (dragElement && dragElement.classList.contains("abc")) {
                const offsetX = e.clientX - dragElement.getBoundingClientRect().left;
                const offsetY = e.clientY - dragElement.getBoundingClientRect().top;
                const edgeThreshold = 15;

                // 检测上边缘
                const elementAbove = document.elementFromPoint(e.clientX, e.clientY - edgeThreshold);
                // 检测下边缘
                const elementBelow = document.elementFromPoint(e.clientX, e.clientY + edgeThreshold);
                // 检测左边缘
                const elementLeft = document.elementFromPoint(e.clientX - edgeThreshold, e.clientY);
                // 检测右边缘
                const elementRight = document.elementFromPoint(e.clientX + edgeThreshold, e.clientY);
                let sort: number = getSort(dragElement)

                // 如果检测到其他元素，可以在这里执行相应的逻辑
                // 例如，你可以通过检查 elementAbove、elementBelow、elementLeft、elementRight 是否为 null 来确定是否接近边缘

                // 以下是示例逻辑，你可以根据需要进行自定义
                $(".abc").removeClass("active");
                if (elementAbove && offsetY < edgeThreshold) {
                    dragElement.classList.add("active")
                    
                    setChange({ from: elementSort, to: sort });
                    // 鼠标接近上边缘，执行相应的逻辑
                    console.log('接近上边缘');
                } else if (elementBelow && (dragElement.clientHeight - offsetY) < edgeThreshold) {
                    setChange({ from: elementSort, to: sort });
                    // 鼠标接近下边缘，执行相应的逻辑
                    console.log('接近下边缘');
                } else if (elementLeft && offsetX < edgeThreshold) {
                    // 鼠标接近左边缘，执行相应的逻辑
                    console.log('接近左边缘');
                } else if (elementRight && (dragElement.clientWidth - offsetX) < edgeThreshold) {
                    // 鼠标接近右边缘，执行相应的逻辑
                    console.log('接近右边缘');
                }
            }
        }
    }, [element, position]);
    useEventListener("mousemove", element && document.body, moveFunc)

    useEventListener("mouseup", element && document.body, () => {
        setElement(undefined);
        setPosition(undefined);
        element && (element.style.transform = "");
        setTimeout(() => {
            $(".abc").removeClass("active");
        }, 0);
        if (change) {
            let top = 0;
            $(".abc").each((index, _element) => {
                if (element !== _element && index >= change.to) {
                    _element.style.top = `${+_element.getAttribute("data-top")! + element!.clientHeight}px`;
                    top += +_element.getAttribute("data-top")!
                }
            })
            element!.style.top = `${top}px`
            setTimeout(() => {
                $(".abc").removeClass("active");
                $(".abc").css("position", "");
                // 修改columns顺序
                if (change) {
                    const _columns = [...columns];
                    const _change = _columns[change.from];
                    _columns.splice(change.from, 1);
                    _columns.splice(change.to - 1, 0, _change);
                    setColumns(_columns);
                }
            }, 400);
        }
        element?.classList.remove("long");
        clearTimer();
    })
    useEventListener("mousedown", document.body, e => {
        const element = findParent(e.target as HTMLElement, "abc");
        if (element) {
            setPosition({ x: e.clientX, y: e.clientY });
            setElement(element);
        }
    })
    useEffect(() => {
        if (!change || !element) {
            return;
        }
        const elements = document.querySelectorAll(".abc") as NodeListOf<HTMLElement>;
        elements.forEach((_element, index) => {
            if (element !== _element && index >= change.to) {
                _element.style.top = `${+_element.getAttribute("data-top")! + 30}px`
            }
            else {
                console.log(+_element.getAttribute("data-top")!)
                _element.style.top = `${+_element.getAttribute("data-top")!}px`
            }
        })
    }, [change, element])

    return { change, element, columns }
}


const FormContainer = () => {
    const { columns } = useLongPress();



    return (
        <div className="form-container" id="form-container" >
            <BetaSchemaForm
                submitter={{
                    "render": () => {
                        return <div className="form-container-submit" >
                            <Space>
                                <Button  type="primary" >提交</Button>
                                <Button>重置</Button>
                            </Space>
                        </div>
                    }
                }}
                className="form-wrap"
                columns={columns.map((p, index) => {
                    return {
                        ...p,
                        formItemProps: {
                            ...p.formItemProps,
                            className: classNames(p.formItemProps?.className, "abc", "abc-" + index)
                        }
                    }
                })}
            />
        </div>
    )
}

export default FormContainer;